package com.example.roleplay.service.asr;

import com.example.roleplay.config.RoleplayProperties;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.UUID;

/**
 * 智谱AI GLM-ASR语音识别客户端实现（基于HTTP API）
 */
@Slf4j
@Service
@RequiredArgsConstructor
@ConditionalOnProperty(name = "roleplay.provider.asr", havingValue = "glm-asr")
public class ZhipuASRClient implements ASRClient {

    private final RoleplayProperties properties;
    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;

    private static final String ASR_ENDPOINT = "/audio/transcriptions";

    @Override
    public String transcribe(MultipartFile audioFile, String language) {
        try {
            log.info("GLM-ASR 识别音频文件: {}, 语言: {}", audioFile.getOriginalFilename(), language);
            
            // 创建临时文件
            File tempFile = createTempFile(audioFile);
            
            try {
                return transcribeFile(tempFile, language);
            } finally {
                // 清理临时文件
                if (tempFile.exists()) {
                    tempFile.delete();
                }
            }
            
        } catch (Exception e) {
            log.error("GLM-ASR 识别失败", e);
            throw new RuntimeException("语音识别失败: " + e.getMessage(), e);
        }
    }

    @Override
    public String transcribe(byte[] audioData, String format, String language) {
        try {
            log.info("GLM-ASR 识别音频数据: {} bytes, 格式: {}, 语言: {}", audioData.length, format, language);
            
            // 创建临时文件
            File tempFile = createTempFile(audioData, format);
            
            try {
                return transcribeFile(tempFile, language);
            } finally {
                // 清理临时文件
                if (tempFile.exists()) {
                    tempFile.delete();
                }
            }
            
        } catch (Exception e) {
            log.error("GLM-ASR 识别失败", e);
            throw new RuntimeException("语音识别失败: " + e.getMessage(), e);
        }
    }

    @Override
    public boolean isHealthy() {
        try {
            // 简单的健康检查 - 检查API密钥和基础URL是否配置
            return properties.getZhipu().getApiKey() != null && 
                   !properties.getZhipu().getApiKey().isEmpty();
        } catch (Exception e) {
            log.warn("GLM-ASR 健康检查失败", e);
            return false;
        }
    }

    @Override
    public String[] getSupportedFormats() {
        return properties.getZhipu().getAsr().getSupportedFormats().toArray(new String[0]);
    }

    @Override
    public String[] getSupportedLanguages() {
        return new String[]{"zh-CN", "en-US", "zh-TW", "ja-JP", "ko-KR"};
    }

    /**
     * 调用GLM-ASR API进行语音识别
     */
    private String transcribeFile(File audioFile, String language) throws IOException {
        String url = properties.getZhipu().getBaseUrl() + ASR_ENDPOINT;
        
        // 准备请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.setBearerAuth(properties.getZhipu().getApiKey());
        
        // 准备multipart请求体
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("model", properties.getZhipu().getAsr().getModel());
        body.add("file", new org.springframework.core.io.FileSystemResource(audioFile));
        body.add("stream", false);
        
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
        
        log.debug("发送GLM-ASR请求: URL={}, 文件={}", url, audioFile.getName());
        
        try {
            ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
            
            if (response.getStatusCode().is2xxSuccessful()) {
                String responseBody = response.getBody();
                log.debug("GLM-ASR API响应: {}", responseBody); // 添加调试日志
                
                JsonNode jsonResponse = objectMapper.readTree(responseBody);
                
                // 尝试不同的JSON路径来获取识别结果
                String text = null;
                if (jsonResponse.has("data")) {
                    text = jsonResponse.path("data").asText();
                } else if (jsonResponse.has("text")) {
                    text = jsonResponse.path("text").asText();
                } else if (jsonResponse.has("result")) {
                    text = jsonResponse.path("result").asText();
                } else if (jsonResponse.has("transcript")) {
                    text = jsonResponse.path("transcript").asText();
                }
                
                log.info("GLM-ASR 识别成功: {}", text);
                return text != null ? text.trim() : "";
            } else {
                String errorMsg = "GLM-ASR 识别失败: HTTP " + response.getStatusCode();
                log.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
        } catch (Exception e) {
            log.error("GLM-ASR API调用失败", e);
            throw new RuntimeException("GLM-ASR API调用失败: " + e.getMessage(), e);
        }
    }

    /**
     * 从MultipartFile创建临时文件
     */
    private File createTempFile(MultipartFile audioFile) throws IOException {
        String originalFileName = audioFile.getOriginalFilename();
        String extension = originalFileName != null && originalFileName.contains(".") 
                ? originalFileName.substring(originalFileName.lastIndexOf("."))
                : ".wav";
        
        File tempFile = File.createTempFile("glm-asr-" + UUID.randomUUID(), extension);
        audioFile.transferTo(tempFile);
        
        log.debug("创建临时文件: {}", tempFile.getAbsolutePath());
        return tempFile;
    }

    /**
     * 从字节数组创建临时文件
     */
    private File createTempFile(byte[] audioData, String format) throws IOException {
        String extension = "." + format.toLowerCase();
        File tempFile = File.createTempFile("glm-asr-" + UUID.randomUUID(), extension);
        
        try (FileOutputStream fos = new FileOutputStream(tempFile)) {
            fos.write(audioData);
        }
        
        log.debug("创建临时文件: {}", tempFile.getAbsolutePath());
        return tempFile;
    }
}